home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
FileDialog.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-24
|
8KB
|
384 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "FileDialog.h"
#include "Class.h"
#include "PopupItem.h"
#include "ImageItem.h"
#include "BorderItems.h"
#include "Buttons.h"
#include "ScrollBar.h"
#include "CollView.h"
#include "OrdColl.h"
#include "Data.h"
#include "Fields.h"
#include "Form.h"
#include "Menu.h"
#include "Alert_e.h"
#include "Scroller.h"
#include "Document.h"
#include "Application.h"
#include "Error.h"
#include "String.h"
const Point cIconSize(16);
//---- FileDialog --------------------------------------------------------------
NewMetaImpl(FileDialog, Dialog, (TP(eti), TP(title), TP(initDir), TE(flags),
TP(collview), TP(doc), TP(pathPopup)));
FileDialog::FileDialog(char *ti) : Dialog(ti)
{
title= new TextItem(ti);
doc= 0;
fileData= 0;
initDir= 0;
pathList= 0;
current= 0;
}
FileDialog::~FileDialog()
{
SafeDelete(fileData);
SafeDelete(initDir);
SafeDelete(collview);
if (pathList) {
pathList->FreeAll();
SafeDelete(pathList);
}
SafeDelete(current);
}
char *FileDialog::FileName()
{
return fileData->FullName();
}
int FileDialog::ShowInWindow(FileDialogFlags f, Clipper *fp, EvtHandler *eh, char *p)
{
flags= f;
doc= eh;
if (p == 0) {
if (f == eFDRead)
p= "Open File Named:";
else if (f == eFDWrite)
p= "Save in File Named:";
else
p= "Import File Named:";
}
title->SetString(p);
// remember initial working directory
strreplace(&initDir, gSystem->WorkingDirectory());
return Dialog::ShowOnWindow(fp);
}
void FileDialog::UpdateList()
{
SafeDelete(current);
current= new FileData(".");
SeqCollection *contents;
contents= current->GetContents();
Iter next(contents);
register Data *d;
VObject *vop;
OrdCollection *files= new OrdCollection;
while (d= (Data*) next())
if (vop= MakeFileItem(d))
files->Add(vop);
files->Sort();
collview->SetCollection(files);
if (eti)
eti->SetString("");
}
VObject *FileDialog::MakeFileItem(Data *data)
{
return new FileItem(data);
}
int FileDialog::ItemHeight()
{
VObject *vop= new FileItem(".", FALSE);
int h= vop->GetMinSize().extent.y;
delete vop;
return h;
}
VObject *FileDialog::DoMakeContent()
{
pathPopup= new PopupButton(cIdPath, cIdNone,
new Menu("Current Directory", FALSE, FALSE));
collview= new CollectionView(this, new OrdCollection, eCVDontStuckToBorder);
collview->SetMinExtent(Point(cItemMinWidth, 0));
collview->SetId(cIdList);
return
new Matte(
new VExpander(20,
new Form(cIdNone, (VObjAlign)(eVObjVBase+eVObjHExpand), gPoint10,
"Current Directory:", pathPopup,
0
),
scroller= new Scroller(collview,
Point(cItemMinWidth, ItemHeight()*cNumItems), cIdList),
new VExpander(gPoint2,
title,
eti= new TextField(cIdName, 20),
0
),
new HBox(20, (VObjAlign)(eVObjVBase|eVObjHEqual|eVObjHExpand),
openButton= new ActionButton(cIdOk, flags == eFDWrite ? "Save" : "Open", TRUE),
new ActionButton(cIdCancel, "Cancel"),
new ActionButton(cIdUpdate, "Update"),
new ActionButton(cHELP, "Help"),
0
),
0
)
);
}
void FileDialog::DoSetDefaults()
{
UpdatePath();
UpdateList();
}
void FileDialog::DoSetup()
{
if (flags == eFDWrite) {
char buf[1000];
eti->GetString(buf, 1000);
FileData *fd= new FileData(buf, FALSE, FALSE);
openButton->SetLabel(fd->IsDirectory() ? "Open" : "Save", TRUE);
delete fd;
}
openButton->Enable(eti->GetTextSize() > 0);
}
void FileDialog::DoRestore()
{
gSystem->ChangeDirectory(initDir);
}
void FileDialog::Control(int id, int p, void *v)
{
VObject *gop;
switch (id) {
case cIdUpdate:
UpdateList();
return;
case cIdList:
switch (p) {
case cPartCollSelect:
gop= (VObject*) collview->GetCollection()->At( (int) v );
char *fname= gop->AsString();
if (fname && strlen(fname) > 0)
eti->SetString(gop->AsString());
break;
case cPartCollDoubleSelect:
if (OpenOrChangeDir()) {
Dialog::Control(cIdOk, cPartAction, v);
return;
}
break;
}
return;
case cIdOk:
if (!OpenOrChangeDir())
return;
break;
case cIdPath:
Data *d= (Data*) pathList->At((int)v-cIdComponent);
if (d)
eti->SetString(d->FullName());
OpenOrChangeDir();
return;
}
Dialog::Control(id, p, v);
}
void FileDialog::InputKbd(Token &t)
{
if (t.IsAscii() && scroller->ContainsPoint(t.Pos)) {
if (t.Code != '\r' && t.Code != '\n')
scroller->Input(t.Pos, t, GetWindow());
} else
Manager::InputKbd(t);
}
bool FileDialog::ChangeDirectory()
{
if (fileData->IsDirectory()) {
if (!gSystem->ChangeDirectory(fileData->FullName()))
ShowAlert(eAlertNote, "Cannot change directory to @B%s@P", fileData->FullName());
else {
UpdatePath();
UpdateList();
}
return TRUE;
}
return FALSE;
}
bool FileDialog::OpenOrChangeDir()
{
char pathname[cPathBuf];
eti->GetString(pathname, cPathBuf);
if (gSystem->ExpandPathName(pathname, cPathBuf-1)) {
ShowAlert(eAlertNote, "%s (%s)", gSystem->GetErrorStr(), pathname);
return FALSE;
}
SafeDelete(fileData);
fileData= new FileData(pathname, FALSE, TRUE); // deep
if (ChangeDirectory())
return FALSE;
char *fname= fileData->FullName();
if (flags == eFDWrite) {
if (!gSystem->AccessPathName(fname, 0)) {
if (ShowAlert(eAlertCaution, "File @B%s@P exists! Overwrite ?", fname) != cIdYes)
return FALSE;
}
if (!fileData->IsWritable()) {
ShowAlert(eAlertNote, "Document @B%s@P is not writable\n%s", fname,
gSystem->GetErrorStr());
return FALSE;
}
} else {
if (!fileData->IsReadable()) {
ShowAlert(eAlertNote, "Can't open document @B%s@P for reading\n%s",
fname, gSystem->GetErrorStr());
return FALSE;
}
if (WrongType()) {
ShowAlert(eAlertNote, "File @B%s@P has wrong type (%s)", fname,
fileData->Type().AsString());
return FALSE;
}
}
return TRUE;
}
bool FileDialog::WrongType()
{
if (doc) {
if (doc->IsKindOf(Document)) {
if (flags == eFDImport)
filterfunc= (FilterFunc) &Document::CanLoad;
else
filterfunc= (FilterFunc) &Document::CanLoad;
} else if (doc->IsKindOf(View)) {
View *v= (View*) doc;
return ! v->CanPaste(fileData);
} else
filterfunc= (FilterFunc) &Application::CanOpen;
return ! (doc->*filterfunc)(fileData);
}
return FALSE;
}
void FileDialog::UpdatePath()
{
Data *here;
if (pathList) {
pathList->FreeAll();
SafeDelete(pathList);
}
pathList= new OrdCollection;
for (here= new FileData("."); here; here= here->GetParent())
pathList->AddFirst(here);
Iter next(pathList);
Data *dp;
SeqCollection *newpath= new OrdCollection;
for (int i= 0; dp= (Data*)next(); i++)
newpath->Add(new MenuButtonItem(cIdComponent+i, dp->ShortName()));
pathPopup->SetCollection(newpath);
pathPopup->SetValue(cIdComponent+i-1);
}
//---- FileItem ----------------------------------------------------------------
NewMetaImpl0(FileItem, VObject);
FileItem::FileItem(char *name, bool shallow) : VObject()
{
data= new FileData(name, FALSE, !shallow); // shallow
}
FileItem::FileItem(Data *d) : VObject()
{
data= d;
}
FileItem::~FileItem()
{
SafeDelete(data);
}
Metric FileItem::GetMinSize()
{
byte *n= (byte*) data->ShortName();
return Metric(gSysFont->Width(n)+20, gSysFont->Spacing()+4, gSysFont->Ascender()+2);
}
char *FileItem::AsString()
{
return data->ShortName();
}
void FileItem::Draw(Rectangle)
{
byte *n= (byte*) data->ShortName();
Point p= contentRect.origin;
p.x+= 22;
p.y+= gSysFont->Ascender()+3;
GrShowString(gSysFont, Enabled() ? ePatBlack : ePatGrey50, p, n);
Bitmap *bm= data->GetBitmap();
if (bm) {
Rectangle br(contentRect.origin, bm->Size());
br.origin.x+= 2;
br.origin.y+= 3;
GrPaintBitMap(br, bm, Enabled() ? ePatBlack : ePatGrey50);
}
}
int FileItem::Compare(Object *op)
{
FileItem *other= Guard(op,FileItem);
/*
bool isdir= data->IsDirectory();
if (isdir == other->GetData()->IsDirectory())
return StrCmp((byte*)data->ShortName(), (byte*)other->data->ShortName(), -1, sortmap);
if (isdir)
return -1;
return 1;
*/
return StrCmp((byte*)data->ShortName(), (byte*)other->data->ShortName(),
-1, sortmap);
}